﻿using System;
using System.ComponentModel;
using nRoute.Components;
using nRoute.Components.Composition;
using nRoute.Components.Disposer;
using nRoute.Samples.OfficerXcel.Model;
using nRoute.Samples.OfficerXcel.Services;
using nRoute.Samples.OfficerXcel.Views;
using nRoute.ViewModels;
using nRoute.Components.Handlers;

namespace nRoute.Samples.OfficerXcel.ViewModels
{
    [MapViewModel(typeof(InfoDialog))]
    public class InfoDialogViewModel
        : NavigationViewModelBase
    {
        private readonly IActiveWorksheetService _activeWorksheetService;
        private Handler<PropertyChangedEventArgs, PropertyChangedEventHandler> _propertyChangedHandler;

        [ResolveConstructor]
        public InfoDialogViewModel(IActiveWorksheetService activeWorksheetService)
        {
            if (activeWorksheetService == null) throw new ArgumentNullException("activeWorksheetService");
            SetupCommands();

            _activeWorksheetService = activeWorksheetService;
            _activeWorksheetService.ActiveWorksheetChanged += ActiveWorksheetService_ActiveWorksheetChanged;            
            SetupActiveWorksheetListeners();
        }

#region Properties

        public ActionCommand OpenWorksheetCommand { get; private set; }

        public ActionCommand SaveWorksheetCommand { get; private set; }

        public ActionCommand CloseWorksheetCommand { get; private set; }

        public Worksheet Worksheet
        {
            get { return _activeWorksheetService.ActiveWorksheet;  }
        }

#endregion

#region Overrides

        protected override ParametersCollection OnSaveState()
        {
            _activeWorksheetService.ActiveWorksheetChanged -= ActiveWorksheetService_ActiveWorksheetChanged;
            if (_propertyChangedHandler != null) _propertyChangedHandler.Dispose();
            return base.OnSaveState();
        }

#endregion

#region Handlers

        public void ActiveWorksheetService_ActiveWorksheetChanged(object sender, EventArgs e)
        {
            SetupActiveWorksheetListeners();
        }

        private void Worksheet_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            SaveWorksheetCommand.IsActive = Worksheet.IsDirty;
        }

#endregion

#region Setup Related

        private void SetupActiveWorksheetListeners()
        {
            if (this.Worksheet == null)
            {
                SaveWorksheetCommand.IsActive = false;
                CloseWorksheetCommand.IsActive = false;
            }
            else
            {
                SaveWorksheetCommand.IsActive = Worksheet.IsDirty;
                CloseWorksheetCommand.IsActive = true;

                if (_propertyChangedHandler != null) _propertyChangedHandler.Dispose();
                var _worksheet = Worksheet;
                _propertyChangedHandler = new Handler<PropertyChangedEventArgs, PropertyChangedEventHandler>(Worksheet_PropertyChanged,
                    (h) => _worksheet.PropertyChanged -= h).DisposeWith(_worksheet.Disposer);
                _worksheet.PropertyChanged += _propertyChangedHandler;
            }
            NotifyPropertyChanged(() => Worksheet);
        }

        private void SetupCommands()
        {
            OpenWorksheetCommand = new ActionCommand(() => _activeWorksheetService.OpenWorksheet());

            SaveWorksheetCommand = new ActionCommand(() => _activeWorksheetService.SaveWorksheet());

            CloseWorksheetCommand = new ActionCommand(() => _activeWorksheetService.CloseActiveWorksheet());
        }

#endregion

    }
}
